package com.haibo.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.haibo.entity.dto.MedicalRecordGenerationDTO;
import com.haibo.entity.dto.MedicalRecordGenerationItemDTO;
import com.haibo.entity.dto.ThreeLevelCardControlReminderDTO;
import com.haibo.entity.dto.ThreeLevelCardControlReminderItemDTO;
import com.haibo.entity.model.MedicalRecordGenerationDO;
import com.haibo.entity.model.MedicalRecordGenerationItemDO;
import com.haibo.entity.model.ThreeLevelCardControlReminderDO;
import com.haibo.exception.BusinessException;
import com.haibo.mapper.MedicalRecordGenerationItemMapper;
import com.haibo.mapper.MedicalRecordGenerationMapper;
import com.haibo.mapper.ThreeLevelCardControlReminderMapper;
import com.haibo.result.R;
import com.haibo.service.ElectronicMedicalRecordService;
import com.haibo.utils.SnowflakeIdGeneratorUtil;
import com.haibo.utils.ThreeLevelCardControlReminderUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author : 刘海波
 * @Date: 2025-09-22 8:08
 * @Description: 【电子病历】
 */
@Slf4j
@Service
public class ElectronicMedicalRecordServiceImpl implements ElectronicMedicalRecordService {

    @Autowired
    private MedicalRecordGenerationMapper medicalRecordGenerationMapper;
    @Autowired
    private MedicalRecordGenerationItemMapper medicalRecordGenerationItemMapper;
    @Autowired
    private ThreeLevelCardControlReminderMapper threeLevelCardControlReminderMapper;


    /**
     * 病历质控-回写病历内容至中间表
     *
     * @param param
     */
    @Override
    public R rewriteMedicalRecordQualityControlData(MedicalRecordGenerationDTO param) {
        // ================================ [更新病历质控] ================================
        Map<String, String> medicalRecordGenerationMap = new HashMap<>();
        medicalRecordGenerationMap.put("patientId", param.getPatientId());
        medicalRecordGenerationMap.put("doctorCode", param.getDoctorCode());
        medicalRecordGenerationMap.put("visitId", param.getVisitId());
        List<MedicalRecordGenerationDO> dbMedicalRecordGenerationDOS = medicalRecordGenerationMapper.listByMap(medicalRecordGenerationMap);

        if (CollectionUtils.isNotEmpty(dbMedicalRecordGenerationDOS)) {
            // 病历质控-主表
            MedicalRecordGenerationDO updatedMedicalRecordGenerationDO = buildMedicalRecordGeneration(param, true);
            try {
                updatedMedicalRecordGenerationDO.setId(dbMedicalRecordGenerationDOS.get(0).getId());
                log.debug("[更新病历质控主表数据至中间表]参数：{}", JSON.toJSONString(updatedMedicalRecordGenerationDO));
                int mainResult = medicalRecordGenerationMapper.updateById(updatedMedicalRecordGenerationDO);
                log.debug("[更新病历质控主表数据至中间表]结果：{}", mainResult);
            } catch (Exception e) {
                log.error("[更新病历质控主表数据至中间表] error:{}", e.getMessage());
                throw new BusinessException("更新病历质控主表数据至中间表失败，请联系管理员！");
            }

            // 病历质控-细表
            try {
                // 病历质控-细表
                medicalRecordGenerationItemMapper.delByMedicalRecordId(dbMedicalRecordGenerationDOS.get(0).getId());
                log.debug("[更新病历质控细表数据至中间表]逻辑删除细表数据成功!主表ID：{}", dbMedicalRecordGenerationDOS.get(0).getId());

                List<MedicalRecordGenerationItemDTO> medicalRecordGenerationItemList = param.getContentList();
                List<MedicalRecordGenerationItemDO> medicalRecordGenerationItemDOList = buildMedicalRecordGenerationItem(medicalRecordGenerationItemList, updatedMedicalRecordGenerationDO);
                log.debug("[更新病历质控细表数据至中间表]参数：{}", JSON.toJSONString(medicalRecordGenerationItemDOList));
                int itemResult = medicalRecordGenerationItemMapper.save(medicalRecordGenerationItemDOList);
                log.debug("[更新病历质控细表数据至中间表]结果：{}", itemResult);
            } catch (Exception e) {
                log.error("[更新病历质控细表数据至中间表] error：{}", e.getMessage());
                throw new BusinessException("更新病历质控细表数据至中间表失败，请联系管理员！");
            }

            return R.success("更新病历质控数据至中间表成功");

        } else {
            // ================================ [新增病历质控] ================================
            // 病历质控-主表
            MedicalRecordGenerationDO medicalRecordGenerationDO = buildMedicalRecordGeneration(param, false);
            try {
                log.debug("[新增病历质控主表数据至中间表]参数：{}", JSON.toJSONString(medicalRecordGenerationDO));
                medicalRecordGenerationMapper.save(medicalRecordGenerationDO);
                log.debug("[新增病历质控主表数据至中间表]结果：{}", JSON.toJSONString(medicalRecordGenerationDO));
            } catch (Exception e) {
                log.error("[新增病历质控主表数据至中间表] error:{}", e.getMessage());
                throw new BusinessException("新增病历质控主表数据至中间表失败，请联系管理员！");
            }

            try {
                // 病历质控-细表
                List<MedicalRecordGenerationItemDTO> medicalRecordGenerationItemList = param.getContentList();
                List<MedicalRecordGenerationItemDO> medicalRecordGenerationItemDOList = buildMedicalRecordGenerationItem(medicalRecordGenerationItemList, medicalRecordGenerationDO);
                log.debug("[新增病历质控细表数据至中间表]参数：{}", JSON.toJSONString(medicalRecordGenerationItemDOList));
                int result = medicalRecordGenerationItemMapper.save(medicalRecordGenerationItemDOList);
                log.debug("[新增病历质控细表数据至中间表]结果：{}", result);
            } catch (Exception e) {
                log.error("[新增病历质控细表数据至中间表] error:{}", e.getMessage());
                throw new BusinessException("新增病历质控细表数据至中间表，请联系管理员！");
            }

            return R.success("新增病历质控数据至中间表成功");
        }
    }

    /**
     * 三级卡控-回写提醒消息至中间表
     * @param param
     * @return
     */
    @Override
    public R rewriteThreeLevelCardControlReminderData(ThreeLevelCardControlReminderDTO param) {
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("scene", param.getScene());
        paramMap.put("visitId", param.getVisitId());
        paramMap.put("patientId", param.getPatientId());
        // ================================ [更新：三级卡控-回写提醒消息] ================================
        List<ThreeLevelCardControlReminderDO> dbThreeLevelCardControlReminderDOList = threeLevelCardControlReminderMapper.listByMap(paramMap);
        if (CollectionUtils.isNotEmpty(dbThreeLevelCardControlReminderDOList)) {
            // 先逻辑删除再新增
            try {
                int result = threeLevelCardControlReminderMapper.delByMap(paramMap);
                log.debug("[三级卡控-回写提醒消息]逻辑删除提醒消息，影响的行数：{}",result);
            } catch (Exception e) {
                log.error("[三级卡控-回写提醒消息]逻辑删除提醒消息失败，原因：{}", e.getMessage());
                return R.fail("逻辑删除[三级卡控：回写提醒消息]失败，请联系管理员！");
            }


            List<ThreeLevelCardControlReminderItemDTO> msgList = param.getMsgList();
            if (CollectionUtils.isEmpty(msgList)) {
                log.error("更新[三级卡控-回写提醒消息]质控消息提醒为空！patientId：{}，visitId：{},scene：{}", param.getPatientId(), param.getVisitId(), param.getScene());
                throw new BusinessException("质控消息提醒不允许为空！");
            }

            try {
                List<ThreeLevelCardControlReminderDO> threeLevelCardControlReminderDOS = ThreeLevelCardControlReminderUtil.buildThreeLevelCardControlReminder(msgList,param);
                log.debug("更新[三级卡控-回写提醒消息]构建结果size：{}", threeLevelCardControlReminderDOS.size());
                log.debug("更新[三级卡控-回写提醒消息]构建结果json：{}", JSON.toJSONString(threeLevelCardControlReminderDOS));

                // 将[三级卡控-回写提醒消息]保存至中间表
                int result = threeLevelCardControlReminderMapper.save(threeLevelCardControlReminderDOS);
                log.debug("更新[三级卡控-回写提醒消息]成功！影响的行数：{}", result);
                return R.success("更新[三级卡控-回写提醒消息]成功！");
            } catch (Exception e) {
                log.error("更新[三级卡控-回写提醒消息]失败！原因：{}", e.getMessage());
                return R.fail("更新[三级卡控-回写提醒消息]失败，请联系管理员！");
            }

        }

        // ================================ [新增：三级卡控-回写提醒消息] ================================
        try {
            // 三级卡控-回写提醒消息
            List<ThreeLevelCardControlReminderDO> threeLevelCardControlReminderDOS = ThreeLevelCardControlReminderUtil.buildThreeLevelCardControlReminder(param.getMsgList(),param);
            log.debug("新增[三级卡控-回写提醒消息]构建结果size：{}", threeLevelCardControlReminderDOS.size());
            log.debug("新增[三级卡控-回写提醒消息]构建结果json：{}", JSON.toJSONString(threeLevelCardControlReminderDOS));

            // 将[三级卡控-回写提醒消息]保存至中间表
            int result = threeLevelCardControlReminderMapper.save(threeLevelCardControlReminderDOS);
            log.debug("新增[三级卡控-回写提醒消息]成功！影响的行数：{}", result);
            return R.success("新增[三级卡控-回写提醒消息]成功！");
        } catch (Exception e) {
            log.error("新增[三级卡控-回写提醒消息]失败！原因：{}", e.getMessage());
            return R.fail("新增[三级卡控-回写提醒消息]失败，请联系管理员！");
        }
    }

    /**
     * 构建[病历质控-细表]数据
     *
     * @param medicalRecordGenerationItemList 病历质控-细表
     * @param medicalRecordGenerationDO       病历质控-主表
     * @return
     */
    private List<MedicalRecordGenerationItemDO> buildMedicalRecordGenerationItem(List<MedicalRecordGenerationItemDTO> medicalRecordGenerationItemList, MedicalRecordGenerationDO medicalRecordGenerationDO) {
        log.debug("构建[病历质控-细表]数据param:{}", JSON.toJSONString(medicalRecordGenerationItemList));
        List<MedicalRecordGenerationItemDO> medicalRecordGenerationItemDOList = medicalRecordGenerationItemList
                .stream()
                .map(e -> {
                    MedicalRecordGenerationItemDO medicalRecordGenerationItemDO = new MedicalRecordGenerationItemDO();
                    // 主键ID
                    medicalRecordGenerationItemDO.setId(SnowflakeIdGeneratorUtil.getInstance(2L).nextId());
                    // 病历生成主表ID
                    medicalRecordGenerationItemDO.setMedicalRecordId(medicalRecordGenerationDO.getId());
                    // 就诊ID
                    medicalRecordGenerationItemDO.setVisitId(medicalRecordGenerationDO.getVisitId());
                    // 病历类型
                    medicalRecordGenerationItemDO.setMedicalCategory(medicalRecordGenerationDO.getMedicalCategory());
                    // label
                    medicalRecordGenerationItemDO.setLabel(e.getLabel());
                    // value
                    medicalRecordGenerationItemDO.setValue(e.getValue());
                    // 病历内容对应序号
                    medicalRecordGenerationItemDO.setSort(e.getSort());
                    // 病历内容结构化后的内容（字段不定、类型不定，根据回写内容决定）
                    medicalRecordGenerationItemDO.setStructContent(ObjectUtil.isNotNull(e.getStructContent()) ? JSON.toJSONString(e.getStructContent()) : "");

                    return medicalRecordGenerationItemDO;
                }).collect(Collectors.toList());
        return medicalRecordGenerationItemDOList;
    }

    /**
     * 构建[病历质控-主表]数据
     *
     * @param param
     * @param flag  true：更新、false：新增
     * @return
     */
    private MedicalRecordGenerationDO buildMedicalRecordGeneration(MedicalRecordGenerationDTO param, Boolean flag) {
        log.debug("构建[病历质控-主表]数据param:{}", JSON.toJSONString(param));
        MedicalRecordGenerationDO medicalRecordGenerationDO = new MedicalRecordGenerationDO();
        if (!flag) {
            // 新增
            medicalRecordGenerationDO.setId(SnowflakeIdGeneratorUtil.getInstance(1L).nextId());
        }
        // 患者ID
        medicalRecordGenerationDO.setPatientId(param.getPatientId());
        // 医生姓名
        medicalRecordGenerationDO.setDoctorName(param.getDoctorName());
        // 医生编号
        medicalRecordGenerationDO.setDoctorCode(param.getDoctorCode());
        // 就诊ID
        medicalRecordGenerationDO.setVisitId(param.getVisitId());
        // 科室编号
        medicalRecordGenerationDO.setDepartmentCode(param.getDepartmentCode());
        // 科室名称
        medicalRecordGenerationDO.setDepartmentName(param.getDepartmentName());
        // 病历类型。1：门诊、2：首程、3：入院记录、5：手术记录、7：出院记录、21：疾病证明书
        medicalRecordGenerationDO.setMedicalCategory(param.getMedicalCategory());
        // 是否已采集。0：未采集、1：已采集，EMR系统回写时使用
        medicalRecordGenerationDO.setCollectStatus(param.getCollectStatus());
        // 采集时间
        medicalRecordGenerationDO.setCollectTime(LocalDateTime.now());

        return medicalRecordGenerationDO;
    }
}
